package com.boarsoft.config.spring;

import java.io.File;
import java.io.FileFilter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.ResourceEntityResolver;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.FileSystemResource;

import com.boarsoft.config.core.ConfigListener;

/**
 * 
 * @author Mac_J
 *
 */
public class SpringXmlListener implements ConfigListener {
	private static final Logger log = LoggerFactory.getLogger(SpringXmlListener.class);

	/** */
	@Autowired
	protected DefaultListableBeanFactory beanFactory;
	/** */
	@Autowired
	protected ConfigurableApplicationContext appCtx;

	/** 相对于当前应用实例运行目录的配置文件存储目录路径 */
	protected String absoluteDir = "";
	/** 相对于当前应用实例运行目录的配置文件存储目录路径 */
	protected String relativeDir = "";
	/** 过滤文件的规则，使用自定义fileFilter时可以不配 */
	protected String regex = "(.*)(\\.xml)$";
	/** */
	protected FileFilter fileFilter = new FileFilter() {
		@Override
		public boolean accept(File f) {
			return f.getName().matches(regex);
		}
	};

	public SpringXmlListener() {
		absoluteDir = this.getClass().getClassLoader()
				.getResource(".").getFile().concat(relativeDir);
	}

	@Override
	public boolean onReady(String rp) {
		String fp = null;
		try {
			fp = this.getAbosultePath(rp);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		if (!fp.endsWith(".xml")) {
			return false;
		}
		// 将XML转换为BEAN
		log.info("Load spring xml from {}", fp);
		XmlBeanDefinitionReader xbdr = new XmlBeanDefinitionReader(beanFactory);
		xbdr.setResourceLoader(appCtx);
		xbdr.setEntityResolver(new ResourceEntityResolver(appCtx));
		try {
			xbdr.loadBeanDefinitions(new FileSystemResource(fp));
			log.info("Load spring xml {} sucessfully", fp);
			return true;
		} catch (Exception e) {
			log.error("Error on load spring xml {}", fp, e);
		}
		return false;
	}

	@Override
	public boolean onRemove(String frp) {
		// TODO 当删除某个配置文件时，删除配置的bean
		return false;
	}

	@Override
	public String getAbosoluteDir() {
		return absoluteDir;
	}

	@Override
	public String getAbosultePath(String rp) throws UnsupportedEncodingException {
		return new StringBuilder(URLDecoder.decode(absoluteDir, "utf-8"))//
				.append(relativeDir).append(rp).toString().substring(1);
	}

	@Override
	public String getAbosultePath() {
		return absoluteDir.concat(relativeDir);
	}

	@Override
	public String getRelativeDir() {
		return relativeDir;
	}

	public void setRelativeDir(String relativePath) {
		this.relativeDir = relativePath;
	}

	public String getRegex() {
		return regex;
	}

	public void setRegex(String regex) {
		this.regex = regex;
	}

	@Override
	public FileFilter getFileFilter() {
		return fileFilter;
	}

	public void setFileFilter(FileFilter fileFilter) {
		this.fileFilter = fileFilter;
	}
}